package com.test.a45;

import java.lang.reflect.Method;

import org.springframework.aop.framework.Advised;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;


@SpringBootApplication
public class A45 {

    public static void main(String[] args) throws Exception {
    
    	test3(args);
    }


    /****
     * 1.演示 spring 代理的设计特点
                依赖注入和初始化影响的是原始对象
                代理与目标是两个对象，二者成员变量并不共用数据
    */
    public static void test1(String[] args) {	 
    	ConfigurableApplicationContext context = SpringApplication.run(A45.class, args);
       Bean1 proxy = context.getBean(Bean1.class);//依赖注入和初始化影响的是原始对象 不会调用代理对象的方法
        System.out.println(proxy.getBean2());//会调用代理对象的方法
       System.out.println(proxy.isInitialized());//会调用代理对象的方法
 
		
	}
    
    /*** 
            * 代理与目标是两个对象，二者成员变量并不共用数据 
     * @param args
     * @throws Exception
     */
    public static void test2(String[] args) throws Exception{
        ConfigurableApplicationContext context = SpringApplication.run(A45.class, args);
        Bean1 proxy = context.getBean(Bean1.class);//依赖注入和初始化影响的是原始对象 不会调用代理对象的方法
        showProxyAndTarget(proxy);
      System.out.println(">>>>>>>>>>>>>>>>>>>");
       System.out.println(proxy.getBean2());  //会初始化值
       System.out.println(proxy.isInitialized());//会初始化值
		
	} 
    
    /****
     * 演示 static 方法、final 方法、private 方法均无法增强
     * @param args
     * @throws Exception
     */
    public static void test3(String[] args) throws Exception{
        ConfigurableApplicationContext context = SpringApplication.run(A45.class, args);
        Bean1 proxy = context.getBean(Bean1.class);//依赖注入和初始化影响的是原始对象 不会调用代理对象的方法
        proxy.m1();
        proxy.m2();
        proxy.m3();
        Method m4 = Bean1.class.getDeclaredMethod("m1");
        m4.setAccessible(true);
        m4.invoke(proxy);

		
	}
 

    /***
               * 目标对象和代理对象的使用
     * @param proxy
     * @throws Exception
     */
	public static void showProxyAndTarget(Bean1 proxy) throws Exception {
        System.out.println(">>>>> 代理中的成员变量");  //不会初始化值 还是默认的值
        System.out.println("\tinitialized=" + proxy.initialized);
        System.out.println("\tbean2=" + proxy.bean2);

        if (proxy instanceof Advised) {
        	Advised advised =(Advised) proxy;
            System.out.println(">>>>> 目标中的成员变量");  //会初始化值
            Bean1 target = (Bean1) advised.getTargetSource().getTarget();
            System.out.println("\tinitialized=" + target.initialized);
            System.out.println("\tbean2=" + target.bean2);
        }
    }

}
